package com.qf.openapi.web.master.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.captcha.ShearCaptcha;
import cn.hutool.core.lang.Console;
import cn.hutool.crypto.digest.DigestUtil;
import com.qf.openapi.web.master.entity.User;
import com.qf.openapi.web.master.service.UserService;
import com.qf.openapi.web.master.utils.Constants;
import com.qf.openapi.web.master.vo.ResultVo;
import com.qf.openapi.web.master.vo.TableVo;
import com.qf.openapi.web.master.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Optional;
import java.util.UUID;

@RestController
@RequestMapping("/user")
@Slf4j //添加该注解后可以使用log对象进行日志打印
public class UserController {
    
    @Autowired
    private UserService userService;
    
    private LineCaptcha lineCaptcha;
    
    @PostMapping("/login")
    public ResultVo login(UserVo userVo, HttpSession session, HttpServletResponse resp){
        
        log.info("username={},password={},capchar={}",userVo.getUsername(),userVo.getPassword(),userVo.getCapchar());
        
        if ("on".equals(userVo.getAutoLogin())) {
            //生成用于免登录的cookie，cookie中的信息包含用户名和密码
            String md5Password = DigestUtil.md5Hex(userVo.getPassword());
            String cookieValue = userVo.getUsername() + "-" + md5Password;
            Cookie cookie = new Cookie(Constants.USER_TOKEN, cookieValue);
            cookie.setPath("/"); //设置cookie为该域的顶级cookie
            cookie.setMaxAge(60*60*24*7*2); //两周有效期
            log.debug("用户设置免登录，cookie={}", cookieValue);
            resp.addCookie(cookie);
            
        }
        
        //1.处理谷歌验证码是否正确
        /*String captcha = (String) session.getAttribute("captcha");
        if (!captcha.equals(userVo.getCapchar())){
            return new ResultVo(-1, "验证码不正确！");
        }*/
        
        //1.处理controller hutool验证码是否正确
        /*if (!lineCaptcha.verify(userVo.getCapchar())){
            return new ResultVo(-1, "验证码不正确！");
        }*/
        
        //1.处理servlet hutool验证码是否正确
        ShearCaptcha captcha = (ShearCaptcha) session.getAttribute(Constants.HUTOOL_CAPCHAR);
        
        if (!captcha.verify(userVo.getCapchar())){
            return new ResultVo(-1, "验证码不正确！");
        }
        
        //2.调用Service层的方法进行登陆验证
        ResultVo resultVo = userService.login(userVo.getUsername(), userVo.getPassword(), session);
    
        log.info("调用Service层方法校验用户名和密码，返回的resultVo={}", resultVo);
        
        return resultVo;
    }
    
    /**
     * 用户注册接口，该接口接受的是文件上传请求
     * @param userVo
     * @param req
     * @param session
     * @return
     * @throws IOException
     */
    @PostMapping("/regist")
    public ResultVo regist(UserVo userVo, HttpServletRequest req, HttpSession session) throws IOException {
        log.info("前端收参到后端为：UserVo={}",userVo);
        
        //1.处理谷歌验证码是否正确
        /*String sessionCaptcha = (String) session.getAttribute("captcha");
        if (!capchar.equals(sessionCaptcha)){
            return new ResultVo(-3, "验证码不正确！");
        }*/
    
        //1.处理hutool验证码是否正确
        /*if (!lineCaptcha.verify(userVo.getCapchar())){
            return new ResultVo(-1, "验证码不正确！");
        }*/
        
        //1.处理servlet hutool验证码是否正确
        ShearCaptcha captcha = (ShearCaptcha) session.getAttribute(Constants.HUTOOL_CAPCHAR);
    
        if (!captcha.verify(userVo.getCapchar())){
            return new ResultVo(-1, "验证码不正确！");
        }
        
    
        //获取web根目录下的指定目录的绝对路径
        String realPath = req.getServletContext().getRealPath("/upload/");
    
        //判断upload目录是否已经存在，如果不存在，则创建
        File dir = new File(realPath);
        if (!dir.exists()){
            dir.mkdirs();
        }
    
        ResultVo resultVo = userService.createUser(userVo, realPath);
    
        log.info("后端插入数据库的resultVo为：resultVo={}",resultVo);
        
        return resultVo;
    }
    
    /**
     * 注册页判断用户名重复失焦事件接口
     * @param username
     * @return
     */
    @GetMapping("/getUserByUsername")
    public ResultVo getUserByUsername(String username){
        log.info("前端收参到后端为：username={}",username);
    
        User user = userService.getUserByUsername(username);
        
        if (user != null){
            return new ResultVo(Constants.FAIL_CODE, "该用户名已重复！");
        } else {
            if (username.length() < 3){
                return new ResultVo(Constants.FAIL_CODE, "该用户名长度不足！");
            } else {
                return new ResultVo(Constants.SUCCESS_CODE, "该用户名可以注册");
            }
        }
    }
    
    /**
     * 回显用户名接口
     * @param session
     * @return
     */

    @GetMapping("/getUser")
    public ResultVo getUsername(HttpSession session){
    
        User user = (User) session.getAttribute(Constants.USER_SESSION_KEY);
        
        if (Optional.ofNullable(user).isPresent()){
            return new ResultVo(Constants.SUCCESS_CODE, "获取登录用户成功！", user);
        } else {
            return new ResultVo(Constants.FAIL_CODE, "获取用户失败！");
        }
    
    }
    
    /**
     * 回显头像接口
     * @param resp
     * @param session
     * @throws IOException
     */
    @RequestMapping("/headPortrait")
    public void getHeadPortrait(HttpServletRequest req ,HttpServletResponse resp, HttpSession session) throws IOException {
        User user = (User) session.getAttribute(Constants.USER_SESSION_KEY);
    
        String fileName = user.getHeadPortrait();
    
        String filePathAndName = req.getServletContext().getRealPath(Constants.UPLOAD_PATH) + File.separator + fileName;
    
        //设置响应头  告知浏览器，要以附件的形式保存内容   filename=浏览器显示的下载文件名
        //resp.setHeader("content-disposition","attachment;filename="+headPortraitPath);
    
        //2.把文件内容写入response对象的输出流中
        IOUtils.copy(Files.newInputStream(Paths.get(filePathAndName)), resp.getOutputStream());
    }
    
    /**
     * hutool验证码接口
     * @param resp
     * @throws IOException
     */
    @RequestMapping("/hutoolcapchar")
    public void getCaptcha(HttpServletResponse resp) throws IOException {
        //定义图形验证码的长和宽
        this.lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);
        
        this.lineCaptcha.write(resp.getOutputStream());
    }
    
    
    /**
     * 用户数据表格分页查询
     * @param page 页号
     * @param limit 页容量
     * @return
     */
    @GetMapping("/getAllUser")
    public TableVo<User> getAllUser(Integer page, Integer limit){
        log.debug("分页查询，page={}， limit={}", page, limit);
    
        TableVo<User> tableVo = userService.getAllUserByPage(page, limit);
        
        log.debug("查询到的结果为：tableVo={}", tableVo);
    
        return tableVo;
        
    }
    
    
    @GetMapping("/getUserByPageHelper")
    public TableVo<User> getUserByPageHelper(Integer page, Integer limit){
        log.debug("分页查询，page={}， limit={}", page, limit);
    
        TableVo<User> tableVo = userService.getUserByPageHelper(page, limit);
    
        log.debug("查询到的结果为：tableVo={}", tableVo);
    
        return tableVo;
    }
    
    
    
    @PostMapping("/add")
    public ResultVo add(User user) throws IOException {
        log.info("前端收参到后端为：User={}",user);
        
        ResultVo resultVo = userService.addUser(user);
    
        log.info("后端插入数据库的resultVo为：resultVo={}",resultVo);
    
        return resultVo;
    }
    
    
    @PostMapping("/update")
    public ResultVo update(User user){
        log.debug("前端收参到后端为：User={}", user);
        
        
        ResultVo resultVo = userService.updateUser(user);
    
        log.info("后端返回给前端的resultVo为：resultVo={}",resultVo);
    
        return resultVo;
    }
    
    
    
    @PostMapping("/del")
    public ResultVo del(Integer[] ids){
        log.debug("ids={}", Arrays.toString(ids));
        
        ResultVo resultVo = userService.delUser(ids);
    
        log.info("后端返回给前端的resultVo为：resultVo={}",resultVo);
    
        return resultVo;
    }
    
    
    /**
     * 带查询条件的接口
     * @param page
     * @param limit
     * @param userVo
     * @return
     */
    @GetMapping("/getUsersByCondition")
    public TableVo<User> getUsersByCondition(Integer page, Integer limit, UserVo userVo){
        
        log.debug("收到的参数：page={}, limit={}, userVo={}", page, limit, userVo);
        
        TableVo<User> tableVo = userService.getUsersByCondition(page, limit, userVo);
        
        return tableVo;
    }
    
    
    @GetMapping("/export")
    public ResultVo export(HttpServletResponse resp, HttpServletRequest req) throws IOException {
        
        //1.调用service层的方法进行数据导出，生成文件
        String realPath = req.getServletContext().getRealPath(Constants.UPLOAD_PATH);
    
        File file = new File(realPath);
    
        if (!file.exists()){
            file.mkdirs();
        }
        
        String filename = Constants.USER_EXPROT_FILENAME;
    
        String filenameAndPath = realPath + File.separator + filename;
    
        userService.getCsvFile(filenameAndPath);
        
        //2.返回包含文件名的resultVo
        return new ResultVo(Constants.SUCCESS_CODE, "导出文件成功", filename);
        
    }
    
    
}
